import { getAttributesByType } from './chart-observer-config.js';

// 创建模板
const lineChartTemplate = document.createElement("template");
lineChartTemplate.innerHTML = `
    <style>
        :host {
            display: block;
            width: 600px;
            height: 300px;
        }
        .chart-container {
            width: 100%;
            height: 100%;
            display: flex; /* 使用flex布局 */
            justify-content: center; /* 水平居中 */
            align-items: center; /* 垂直居中 */
        }
    </style>
    <div class="chart-container"></div>
`;

class LineChartComponent extends HTMLElement {
    constructor() {
        super();

        // 创建 Shadow DOM
        const shadow = this.attachShadow({ mode: 'open' });

        // 克隆模板内容
        shadow.appendChild(lineChartTemplate.content.cloneNode(true));

        // 获取图表容器
        const chartDiv = shadow.querySelector('.chart-container');

        // 初始化定时器和图表实例
        this.timerId = null;
        this.chart = echarts.init(chartDiv);
    }

    connectedCallback() {
        const getAttributeWithDefault = (name, defaultValue) => this.getAttribute(name) || defaultValue;

        // key 生成规则：从第一个 - 后开始截取到 _ 前，- 转驼峰
        const normalizeKey = (attrName) => {
            const dashIndex = attrName.indexOf('-');
            if (dashIndex === -1) return attrName;
            const subStr = attrName.substring(dashIndex + 1, attrName.indexOf('_', dashIndex));
            return subStr.split('-').map((part, i) =>
                i === 0 ? part : part.charAt(0).toUpperCase() + part.slice(1)
            ).join('');
        };

        // 通用构造 config
        const buildConfig = (attrList) => {
            const cfg = {};
            attrList.forEach(([attrName, defaultValue]) => {
                // 处理属性值
                let val = getAttributeWithDefault(attrName, defaultValue);
                // 处理布尔值
                if (typeof defaultValue === 'boolean') {
                    val = this.getAttribute(attrName) !== null
                        ? this.getAttribute(attrName).toLowerCase() === 'true'
                        : defaultValue;
                }
                // 处理数字值
                if (typeof defaultValue === 'number') {
                    // 处理百分比值
                    val = parseFloat(val);
                }
                // 处理数组值
                if (attrName.endsWith('_array')) {
                    val = (val || '').split(',');
                }
                cfg[normalizeKey(attrName)] = val;
            });
            return cfg;
        };

        // 定义属性清单
        const titleAttrs = [
            ['title-text_text', '销售数据趋势'],
            ['title-show_radio', true],
            ['title-left_slider', 'center'],
            ['title-top_slider', ''],
            ['title-right_slider', ''],
            ['title-bottom_slider', ''],
            ['title-textalign_select', 'center'],
            ['title-textstyle-color_colorpicker', '#333'],
            ['title-textstyle-fontsize_number', 18],
            ['title-textstyle-fontweight_select', 'bold'],
            ['title-subtext_text', '2023年度数据'],
            ['title-subtextstyle-color_colorpicker', '#666'],
            ['title-subtextstyle-fontsize_number', 14],
            ['title-subtextstyle-fontweight_select', 'normal'],
        ];
        const gridAttrs = [
            ['grid-left_slider', '10%'],
            ['grid-right_slider', '5%'],
            ['grid-bottom_slider', '15%'],
            ['grid-top_slider', '15%'],
            ['grid-containlabel_radio', true],
        ];
        const xAxisAttrs = [
            ['xaxis-nametextstyle-color_colorpicker', '#666'],
            ['xaxis-show_radio', true],
            ['xaxis-name_text', '月份'],
            ['xaxis-nametextstyle-fontsize_number', 12],
            ['xaxis-nametextstyle-fontstyle_select', 'normal'],
            ['xaxis-axislabel-color_colorpicker', '#666'],
            ['xAxis-data-textStyle-fontStyle_colorpicker', 'normal'],
            ['xaxis-axislabel-rotate_number', 0],
            ['xaxis-type_text', 'category'],
            ['xaxis-data_array', JSON.stringify(["1月", "2月", "3月", "4月", "5月", "6月"])],
            ['xaxis-axisline-show_radio', true],
            ['xaxis-axisline-linestyle-color_colorpicker', '#999'],
            ['xaxis-axistick-alignwithlabel_radio', true]
        ];
        const yAxisAttrs = [
            ['yaxis-show_radio', true],
            ['yaxis-name_text', '销售额'],
            ['yaxis-nametextstyle-color_colorpicker', '#666'],
            ['yaxis-nametextstyle-fontsize_number', 12],
            ['yaxis-axislabel-color_colorpicker', '#666'],
            ['yaxis-axislabel-rotate_number', 0],
            ['yaxis-nametextstyle-fontstyle', 'normal'],
            ['yaxis-type_text', 'value'],
            ['yaxis-data_array', ''],
            ['yaxis-splitline-show_radio', false],
            ['yaxis-splitline-linestyle-type_select', 'dashed'],
            ['yaxis-splitline-linestyle-color_colorpicker', '#eee'],
            ['yaxis-axisline-show_radio', true],
            ['yaxis-axisline-linestyle-color_colorpicker', '#999']
        ];
        const legendAttrs = [
            ['legend-show_radio', true],
            ['legend-textstyle-color_colorpicker', '#666'],
            ['legend-itemstyle-color_colorpicker', 'auto'],
            ['legend-itemheight_number', 14],
            ['legend-itemwidth_number', 25],
            ['legend-bottom_number', "90%"],
            ['legend-left_number', '"50"'],
            ['legend-itemgap_number', 20],
            ['legend-textstyle-fontsize_number', 12]
        ];
        // 折线图特有的系列属性
        const seriesAttrs = [
            ['series-name_text', '销售额'],
            ['series-type_select', 'line'],
            ['series-symbol_select', 'circle'],
            ['series-symbol-size_number', 8],
            ['series-show-symbol_radio', true],
            ['series-connect-null_radio', false],
            ['series-smooth_radio', false],
            ['series-smooth-monotone_select', 'none'],
            ['series-line-style-width_number', 2],
            ['series-line-style-color_colorpicker', '#C1232B'],
            ['series-line-style-type_select', 'solid'],
            ['series-line-style-opacity_slider', 1],
            ['series-itemstyle-color_colorpicker', '#C1232B'],
            ['series-itemstyle-bordercolor_colorpicker', '#fff'],
            ['series-itemstyle-bordersize_number', 2],
            ['series-area-style-show_radio', false],
            ['series-area-style-color_colorpicker', 'rgba(193, 35, 43, 0.2)'],

            ['series-label-show_radio', true],
            ['series-label-position_select', 'top'],
            ['series-label-color_colorpicker', '#333'],
            ['series-label-fontsize_number', 12],
            ['series-label-fontweight_select', 'bold'],
            ['series-emphasis-itemstyle-shadowblur_number', 10],
            ['series-emphasis-itemstyle-shadowcolor_colorpicker', 'rgba(0, 0, 0, 0.5)'],

            ['base-data-url_text', ''],
            ['base-echart-init-script_text', ''],
        ];

        // 生成 config
        const titleConfig = buildConfig(titleAttrs);
        const gridConfig = buildConfig(gridAttrs);
        const xAxisConfig = buildConfig(xAxisAttrs);
        const yAxisConfig = buildConfig(yAxisAttrs);
        const legendConfig = buildConfig(legendAttrs);
        const seriesConfig = buildConfig(seriesAttrs);

        // 调整初始大小
        this.resizeChart();
        window.addEventListener('resize', this.resizeChart.bind(this));
        if (ResizeObserver) {
            this.observer = new ResizeObserver(() => this.resizeChart());
            this.observer.observe(this.parentElement);
        }

        // 加载数据并渲染
        if (seriesConfig.dataUrl) {
            fetch(seriesConfig.dataUrl).then(res => res.json()).then(data => {
                let dataDemo = data;

                // 生成series数组（遍历所有数据组）
                const series = dataDemo.map((item, index) => {
                    // 获取当前组的键名（如"销售"）
                    const key = Object.keys(item)[0];
                    // 为避免名称重复，添加索引区分（如"销售1"、"销售2"）
                    const seriesName = `${key}${index + 1}`;
                    // 当前组的数据集
                    const dataList = item[key];

                    return {
                        name: seriesName, // 系列名称（带索引区分）
                        data: dataList.map(item => item.value), // 提取value作为数据
                        type: 'line',
                        symbol: seriesConfig.symbol,
                        symbolSize: seriesConfig.symbolSize,
                        showSymbol: seriesConfig.showSymbol,
                        connectNulls: seriesConfig.connectNull,
                        smooth: seriesConfig.smooth,
                        smoothMonotone: seriesConfig.smoothMonotone,
                        lineStyle: {
                            width: seriesConfig.lineStyleWidth,
                            color: seriesConfig.lineStyleColor,
                            type: seriesConfig.lineStyleType,
                            opacity: seriesConfig.lineStyleOpacity
                        },
                        itemStyle: {
                            color: seriesConfig.itemstyleColor,
                            borderColor: seriesConfig.itemstyleBordercolor,
                            borderWidth: seriesConfig.itemstyleBordersize
                        },
                        areaStyle: {
                            show: seriesConfig.areaStyleShow,
                            color: seriesConfig.areaStyleColor
                        },
                        label: {
                            show: seriesConfig.labelShow,
                            position: seriesConfig.labelPosition,
                            color: seriesConfig.labelColor,
                            fontSize: seriesConfig.labelFontsize,
                            fontWeight: seriesConfig.labelFontweight
                        },
                        emphasis: {
                            itemStyle: {
                                shadowBlur: seriesConfig.emphasisItemstyleShadowblur,
                                shadowColor: seriesConfig.emphasisItemstyleShadowcolor
                            }
                        }
                    };
                });

                // 确保X轴数据与所有系列的name对应
                xAxisConfig.data = dataDemo[0][Object.keys(dataDemo[0])[0]].map(item => item.name);

                const option = {
                    grid: {
                        left: gridConfig.left,
                        right: gridConfig.right,
                        bottom: gridConfig.bottom,
                        top: gridConfig.top,
                        containLabel: gridConfig.containlabel,
                    },
                    title: {
                        show: titleConfig.show,
                        text: titleConfig.text,
                        left: titleConfig.left,
                        right: titleConfig.right,
                        top: titleConfig.top,
                        bottom: titleConfig.bottom,
                        textAlign: titleConfig.textalign,
                        textStyle: {
                            color: titleConfig.textstyleColor,
                            fontSize: titleConfig.textstyleFontsize,
                            fontWeight: titleConfig.textstyleFontweight,
                        },
                        subtext: titleConfig.subtext,
                        subtextStyle: {
                            color: titleConfig.subtextstyleColor,
                            fontSize: titleConfig.subtextstyleFontsize,
                            fontWeight: titleConfig.subtextstyleFontweight,
                        },
                    },
                    legend: {
                        show: legendConfig.show,
                        bottom: legendConfig.bottom,
                        left: legendConfig.left,
                        itemWidth: legendConfig.itemwidth,
                        itemHeight: legendConfig.itemheight,
                        textStyle: {
                            color: legendConfig.textstyleColor ,
                            fontSize: legendConfig.textstyleFontsize
                        },
                        itemStyle: {
                            color: legendConfig.itemstyleColor
                        },
                        itemGap: legendConfig.itemgap,
                    },
                    xAxis: {
                        show: xAxisConfig.show,
                        name: xAxisConfig.name,
                        nameTextStyle: {
                            color: xAxisConfig.nametextstyleColor,
                            fontSize: xAxisConfig.nametextstyleFontsize,
                            fontStyle: xAxisConfig.nametextstyleFontstyle,
                        },
                        type: xAxisConfig.type,
                        data: xAxisConfig.data,
                        axisLabel: {
                            color: xAxisConfig.nametextstyleColor,
                            rotate: xAxisConfig.axislabelRotate,
                            textStyle: { fontStyle: xAxisConfig.nametextstyleFontstyle }
                        },
                        axisTick: {
                            alignWithLabel: true
                        },

                    },
                    yAxis: {
                        show: yAxisConfig.show,
                        name: yAxisConfig.name,
                        type: yAxisConfig.type,
                        data: yAxisConfig.data,

                        nameTextStyle: {
                            color: yAxisConfig.nameTextStyleColor,
                            fontSize: yAxisConfig.nameTextStyleFontSize,
                            fontStyle: yAxisConfig.nameTextStyleFontStyle,
                        },
                        axisLabel: {
                            color: yAxisConfig.nameTextStyleColor,
                            rotate: yAxisConfig.axisLabelRotate,
                            textStyle: { fontStyle: yAxisConfig.nameTextStyleFontStyle }
                        },
                        splitLine: {
                            show: yAxisConfig.splitLineShow,
                            lineStyle: {
                                type: 'dashed',
                                color: '#eee'
                            }
                        },
                    },
                    series: series
                };
                this.chart.setOption(option);

            });
        }

        // 执行外部初始化脚本
        if (seriesConfig.echartInitScript) {
            try { eval(seriesConfig.echartInitScript); } catch (e) { console.error(e); }
        }
    }

    /**
     * 监听的属性
     * @returns {string[]}
     */
    static get observedAttributes() {
        return getAttributesByType('line');
    }

    disconnectedCallback() {
        // 移除 resize 事件监听器以避免内存泄漏
        window.removeEventListener('resize', this.resizeChart.bind(this));

        // 停止观察父容器的大小变化
        if (this.observer) {
            this.observer.disconnect();
        }
        // 清除定时器以避免内存泄漏
        clearInterval(this.timerId);
    }

    // 定时器
    setTimer(interval) {
        // 清除之前的定时器
        clearInterval(this.timerId);
        // 创建新的定时器
        if (interval > 0){
            this.timerId = setInterval(() => {
                this.executeScript();
            }, interval);
        }
    }

    executeScript(){
        if (this.echarttimerscript != ""){
            try {
                eval(this.echarttimerscript);
            } catch (error) {
                console.log(error.message);
            }
        }
        else{
            console.log("no script to execute");
        }
    }

    // 监听容器大小变化并重新调整图表
    resizeChart() {
        // 调整图表大小
        this.chart.resize();
    }

    // 提供一个方法来获取 ECharts 实例
    getChartInstance() {
        return this.chart;
    }

    // 更新数据
    async updateData(){
        try {
            const fullUrl = this.dataurl;
            const response = await fetch(fullUrl);
            if (!response.ok) {
                throw new Error(`HTTP error! Status: ${response.status}`);
            }
            const data = await response.json();
            if (data){
                this.chart.setOption({
                    xAxis: {
                        data:data.xdata
                    },
                    series: [{
                        data:data.ydata
                    }]
                });
            }
        } catch (error) {
            console.log(`错误: ${error.message}`);
        }
    }

    // 属性变化监听的时候调用
    attributeChangedCallback(name, oldValue, newValue) {
        if (name && newValue !== oldValue) {
            const currentOptions = this.chart.getOption();
            if (!currentOptions) return;

            switch (name) {
                // 标题相关属性
                case 'title-show_radio':
                    currentOptions.title[0].show = newValue === "true";
                    this.chart.setOption(currentOptions);
                    break;
                case 'title-text_text':
                    currentOptions.title[0].text = newValue;
                    this.chart.setOption(currentOptions);
                    break;
                case 'title-textstyle-color_colorpicker':
                    currentOptions.title[0].textStyle.color = newValue;
                    this.chart.setOption(currentOptions);
                    break;
                case 'title-textstyle-fontsize_number':
                    currentOptions.title[0].textStyle.fontSize = parseInt(newValue);
                    this.chart.setOption(currentOptions);
                    break;
                case 'title-textstyle-fontweight_select':
                    currentOptions.title[0].textStyle.fontWeight = newValue;
                    this.chart.setOption(currentOptions);
                    break;
                case 'title-subtext_text':
                    currentOptions.title[0].subtext = newValue;
                    this.chart.setOption(currentOptions);
                    break;
                case 'title-subtextstyle-color_colorpicker':
                    currentOptions.title[0].subtextStyle.color = newValue;
                    this.chart.setOption(currentOptions);
                    break;
                case 'title-subtextstyle-fontsize_number':
                    currentOptions.title[0].subtextStyle.fontSize = parseInt(newValue);
                    this.chart.setOption(currentOptions);
                    break;
                case 'title-left_slider':
                    currentOptions.title[0].left = `${newValue}%`;
                    this.chart.setOption(currentOptions);
                    break;
                case 'title-top_slider':
                    currentOptions.title[0].top = `${newValue}%`;
                    this.chart.setOption(currentOptions);
                    break;

                // 网格相关属性
                case 'grid-left_slider':
                    currentOptions.grid[0].left = `${newValue}%`;
                    this.chart.setOption(currentOptions);
                    break;
                case 'grid-right_slider':
                    currentOptions.grid[0].right = `${newValue}%`;
                    this.chart.setOption(currentOptions);
                    break;
                case 'grid-bottom_slider':
                    currentOptions.grid[0].bottom = `${newValue}%`;
                    this.chart.setOption(currentOptions);
                    break;
                case 'grid-top_slider':
                    currentOptions.grid[0].top = `${newValue}%`;
                    this.chart.setOption(currentOptions);
                    break;

                // X轴相关属性
                case 'xaxis-show_radio':
                    currentOptions.xAxis[0].show = newValue === "true";
                    this.chart.setOption(currentOptions);
                    break;
                case 'xaxis-name_text':
                    currentOptions.xAxis[0].name = newValue;
                    this.chart.setOption(currentOptions);
                    break;
                case 'xaxis-nametextstyle-color_colorpicker':
                    currentOptions.xAxis[0].nameTextStyle.color = newValue;
                    this.chart.setOption(currentOptions);
                    break;
                case 'xaxis-axislabel-rotate_number':
                    currentOptions.xAxis[0].axisLabel.rotate = parseInt(newValue);
                    this.chart.setOption(currentOptions);
                    break;
                case 'xaxis-vertical-show_radio':
                    const isVertical = newValue === 'true';
                    let categories = [];

                    if (isVertical) {
                        categories = currentOptions.xAxis?.[0]?.data || [];
                    } else {
                        categories = currentOptions.yAxis?.[0]?.data || [];
                    }

                    if (isVertical) {
                        currentOptions.xAxis[0].type = 'value';
                        currentOptions.yAxis[0].type = 'category';
                        currentOptions.xAxis[0].data = [];
                        currentOptions.yAxis[0].data = categories;
                    } else {
                        currentOptions.xAxis[0].type = 'category';
                        currentOptions.yAxis[0].type = 'value';
                        currentOptions.xAxis[0].data = categories;
                        currentOptions.yAxis[0].data = [];
                    }
                    this.chart.setOption(currentOptions, true);
                    break;

                // Y轴相关属性
                case 'yaxis-show_radio':
                    currentOptions.yAxis[0].show = newValue === "true";
                    this.chart.setOption(currentOptions);
                    break;
                case 'yaxis-name_text':
                    currentOptions.yAxis[0].name = newValue;
                    this.chart.setOption(currentOptions);
                    break;
                case 'yaxis-nametextstyle-color_colorpicker':
                    currentOptions.yAxis[0].nameTextStyle.color = newValue;
                    this.chart.setOption(currentOptions);
                    break;
                case 'yaxis-splitline-show_radio':
                    currentOptions.yAxis[0].splitLine.show = newValue === "true";
                    this.chart.setOption(currentOptions);
                    break;

                // 图例相关属性
                case 'legend-show_radio':
                    currentOptions.legend[0].show = newValue === "true";
                    this.chart.setOption(currentOptions);
                    break;
                case 'legend-textstyle-color_colorpicker':
                    currentOptions.legend[0].textStyle.color = newValue;
                    this.chart.setOption(currentOptions);
                    break;
                case 'legend-textstyle-fontsize_number':
                    currentOptions.legend[0].textStyle.fontSize = parseInt(newValue);
                    this.chart.setOption(currentOptions);
                    break;
                case 'legend-bottom_number':
                    currentOptions.legend[0].bottom = `${newValue}%`;
                    this.chart.setOption(currentOptions);
                    break;
                case 'legend-left_number':
                    currentOptions.legend[0].left = `${newValue}%`;
                    this.chart.setOption(currentOptions);
                    break;

                // 折线图特有属性
                case 'series-symbol_select':
                    if (currentOptions.series.length > 0) {
                        currentOptions.series.forEach(series => {
                            series.symbol = newValue;
                        });
                        this.chart.setOption(currentOptions);
                    }
                    break;
                case 'series-symbol-size_number':
                    if (currentOptions.series.length > 0) {
                        currentOptions.series.forEach(series => {
                            series.symbolSize = parseInt(newValue);
                        });
                        this.chart.setOption(currentOptions);
                    }
                    break;
                case 'series-show-symbol_radio':
                    if (currentOptions.series.length > 0) {
                        currentOptions.series.forEach(series => {
                            series.showSymbol = newValue === "true";
                        });
                        this.chart.setOption(currentOptions);
                    }
                    break;
                case 'series-smooth_radio':
                    if (currentOptions.series.length > 0) {
                        currentOptions.series.forEach(series => {
                            series.smooth = newValue === "true";
                        });
                        this.chart.setOption(currentOptions);
                    }
                    break;
                case 'series-line-style-width_number':
                    if (currentOptions.series.length > 0) {
                        currentOptions.series.forEach(series => {
                            if (!series.lineStyle) series.lineStyle = {};
                            series.lineStyle.width = parseInt(newValue);
                        });
                        this.chart.setOption(currentOptions);
                    }
                    break;
                case 'series-line-style-color_colorpicker':
                    if (currentOptions.series.length > 0) {
                        currentOptions.series.forEach(series => {
                            if (!series.lineStyle) series.lineStyle = {};
                            series.lineStyle.color = newValue;
                        });
                        this.chart.setOption(currentOptions);
                    }
                    break;
                case 'series-line-style-type_select':
                    if (currentOptions.series.length > 0) {
                        currentOptions.series.forEach(series => {
                            if (!series.lineStyle) series.lineStyle = {};
                            series.lineStyle.type = newValue;
                        });
                        this.chart.setOption(currentOptions);
                    }
                    break;
                case 'series-itemstyle-color_colorpicker':
                    if (currentOptions.series.length > 0) {
                        currentOptions.series.forEach(series => {
                            if (!series.itemStyle) series.itemStyle = {};
                            series.itemStyle.color = newValue;
                        });
                        this.chart.setOption(currentOptions);
                    }
                    break;
                case 'series-area-style-show_radio':
                    if (currentOptions.series.length > 0) {
                        currentOptions.series.forEach(series => {
                            if (!series.areaStyle) series.areaStyle = {};
                            series.areaStyle.show = newValue === "true";
                        });
                        this.chart.setOption(currentOptions);
                    }
                    break;
                case 'series-area-style-color_colorpicker':
                    if (currentOptions.series.length > 0) {
                        currentOptions.series.forEach(series => {
                            if (!series.areaStyle) series.areaStyle = {};
                            series.areaStyle.color = newValue;
                        });
                        this.chart.setOption(currentOptions);
                    }
                    break;

                // 数据标签相关属性
                case 'series-label-show_radio':
                    if (currentOptions.series.length > 0) {
                        currentOptions.series.forEach(series => {
                            if (!series.label) series.label = {};
                            series.label.show = newValue === "true";
                        });
                        this.chart.setOption(currentOptions);
                    }
                    break;
                case 'series-label-position_select':
                    if (currentOptions.series.length > 0) {
                        currentOptions.series.forEach(series => {
                            if (!series.label) series.label = {};
                            series.label.position = newValue;
                        });
                        this.chart.setOption(currentOptions);
                    }
                    break;
                case 'series-label-color_colorpicker':
                    if (currentOptions.series.length > 0) {
                        currentOptions.series.forEach(series => {
                            if (!series.label) series.label = {};
                            series.label.color = newValue;
                        });
                        this.chart.setOption(currentOptions);
                    }
                    break;
                case 'series-label-fontsize_number':
                    if (currentOptions.series.length > 0) {
                        currentOptions.series.forEach(series => {
                            if (!series.label) series.label = {};
                            series.label.fontSize = parseInt(newValue);
                        });
                        this.chart.setOption(currentOptions);
                    }
                    break;

                // 数据和脚本相关
                case 'base-echart-timer':
                    this.setTimer(parseInt(newValue) * 1000);
                    break;
                case 'base-echart-timer-script':
                    this.echarttimerscript = newValue;
                    break;
                case 'base-echart-init-script':
                    try {
                        eval(newValue);
                    } catch (error) {
                        console.log(error.message);
                    }
                    break;
                case 'base-data-url':
                    this.dataurl = newValue;
                    this.updateData();
                    break;
            }
        }
    }
}

// 定义新的 HTML 元素
customElements.define('line1-chart-component', LineChartComponent);
